﻿using System;

namespace RAP.Framework.Libary.Utils
{
	/// <summary>
	/// 日期对象扩展
	/// </summary>
	public static partial class Extensions
	{
		#region 日期对象扩展

		/// <summary>
		/// 获取当前日期对应的季度
		/// </summary>
		/// <param name="date"></param>
		/// <returns></returns>
		public static int Quarter ( this DateTime date )
		{
			switch ( date.Month )
			{
				case 1:
				case 2:
				case 3:
					return string.Format ( "{0}{1}", date.Year, 1 ).ToInt32Value ( );

				case 4:
				case 5:
				case 6:
					return string.Format ( "{0}{1}", date.Year, 2 ).ToInt32Value ( );

				case 7:
				case 8:
				case 9:
					return string.Format ( "{0}{1}", date.Year, 3 ).ToInt32Value ( );

				case 10:
				case 11:
				case 12:
					return string.Format ( "{0}{1}", date.Year, 4 ).ToInt32Value ( );
			}
			return 0;
		}

		/// <summary>
		/// 获取当前日期所属年份的季度
		/// </summary>
		/// <param name="date"></param>
		/// <returns></returns>
		public static int QuarterOfYear ( this DateTime date )
		{
			switch ( date.Month )
			{
				case 1:
				case 2:
				case 3:
					return 1;

				case 4:
				case 5:
				case 6:
					return 2;

				case 7:
				case 8:
				case 9:
					return 3;

				case 10:
				case 11:
				case 12:
					return 4;
			}
			return 0;
		}

		/// <summary>
		/// 获取当前日期对应的季度的第一天
		/// </summary>
		/// <param name="date"></param>
		/// <returns></returns>
		public static DateTime? QuarterFirstDay ( this DateTime date )
		{
			switch ( date.Month )
			{
				case 1:
				case 2:
				case 3:
					return string.Format ( "{0}-01-01", date.Year ).ToDateTimeValue ( ).Value;

				case 4:
				case 5:
				case 6:
					return string.Format ( "{0}-04-01", date.Year ).ToDateTimeValue ( ).Value;

				case 7:
				case 8:
				case 9:
					return string.Format ( "{0}-07-01", date.Year ).ToDateTimeValue ( ).Value;

				case 10:
				case 11:
				case 12:
					return string.Format ( "{0}-10-01", date.Year ).ToDateTimeValue ( ).Value;
			}
			return null;
		}

		/// <summary>
		/// 获取当前日期对应的季度的最后一天
		/// </summary>
		/// <param name="date"></param>
		/// <returns></returns>
		public static DateTime? QuarterLastDay ( this DateTime date )
		{
			switch ( date.Month )
			{
				case 1:
				case 2:
				case 3:
					return string.Format ( "{0}-03-31", date.Year ).ToDateTimeValue ( );

				case 4:
				case 5:
				case 6:
					return string.Format ( "{0}-06-30", date.Year ).ToDateTimeValue ( );

				case 7:
				case 8:
				case 9:
					return string.Format ( "{0}-09-30", date.Year ).ToDateTimeValue ( );

				case 10:
				case 11:
				case 12:
					return string.Format ( "{0}-12-31", date.Year ).ToDateTimeValue ( );
			}
			return null;
		}

		/// <summary>
		/// 获取当月的第一天
		/// </summary>
		/// <param name="date"></param>
		/// <returns></returns>
		public static DateTime MonthFirstDay ( this DateTime date )
		{
			return date.ToString ( "yyyy-MM-01" ).ToDateTimeValue ( ).Value;
		}

		/// <summary>
		/// 获取当月的最后一天
		/// </summary>
		/// <param name="date"></param>
		/// <returns></returns>
		public static DateTime MonthLastDay ( this DateTime date )
		{
			return date.AddMonths ( 1 ).MonthFirstDay ( ).AddDays ( -1 );
		}

		/// <summary>
		/// 获取日期对象的日期字符串
		/// </summary>
		/// <param name="date"></param>
        /// <param name="format">格式化参数</param>
		/// <returns></returns>
		public static string ToDateString ( this DateTime date , string format = "yyyy-MM-dd" )
		{
			return date.ToString ( format );
		}

        /// <summary>
        /// 获取日期对象的日期、时间字符串
        /// </summary>
        /// <param name="date"></param>
        /// <param name="format">格式化参数</param>
        /// <returns></returns>
        public static string ToDateTimeString( this DateTime date, string format = "yyyy-MM-dd HH:mm:ss" )
        {
            return date.ToString( format );
        }

        /// <summary>
        /// 获取当前日期所在周的周日的日期
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public static DateTime WeekEndDay ( this DateTime date )
		{
			DayOfWeek day = date.DayOfWeek;
			if ( day == DayOfWeek.Sunday )
			{
				return date;
			}
			return date.AddDays ( 7 - ( int )day );
		}

		/// <summary>
		/// 获取当前日期所在周的周一的日期
		/// </summary>
		/// <param name="date"></param>
		/// <returns></returns>
		public static DateTime WeekFirstDay ( this DateTime date )
		{
			DayOfWeek day = date.DayOfWeek;
			if ( day == DayOfWeek.Sunday )
			{
				return date.AddDays ( ( int )day - 6 );
			}
			return date.AddDays ( 1 - ( int )day );
		}

		/// <summary>
		/// 获取当前日期所在周的下一周的第一天日期
		/// </summary>
		/// <param name="date"></param>
		/// <returns></returns>
		public static DateTime NextWeek ( this DateTime date )
		{
			return date.AddDays ( 7 ).WeekFirstDay ( );
		}

		/// <summary>
		/// 获取当前日期所在周的上一周的第一天日期
		/// </summary>
		/// <param name="date"></param>
		/// <returns></returns>
		public static DateTime PreviousWeek ( this DateTime date )
		{
			return date.AddDays ( -7 ).WeekFirstDay ( );
		}

		/// <summary>
		/// 获取日期从1900-01-01开始计算的周的Id
		/// </summary>
		/// <param name="date"></param>
		/// <returns></returns>
		public static int WeekId ( this DateTime date )
		{
			return ( int )Math.Floor ( date.Subtract ( "1900-01-01".ToDateTimeValue ( ).Value ).TotalDays / 7 );
		}

		/// <summary>
		/// 获取日期从1900-01-01开始计算的月的Id
		/// </summary>
		/// <param name="date"></param>
		/// <returns></returns>
		public static int MonthId ( this DateTime date )
		{
			return ( date.Year - 1900 ) * 12 + date.Month - 1;
		}

		/// <summary>
		/// 获取日期从1900-01-01开始计算的季度的Id
		/// </summary>
		/// <param name="date"></param>
		/// <returns></returns>
		public static int QuarterId ( this DateTime date )
		{
			return ( date.Year - 1900 ) * 4 + date.QuarterOfYear ( ) - 1;
		}

		/// <summary>
		/// 当前时间对应的下一个季度的第一天
		/// </summary>
		/// <param name="date"></param>
		/// <returns></returns>
		public static DateTime NextQuarter ( this DateTime date )
		{
			return date.QuarterLastDay ( ).Value.AddDays ( 1 );
		}

		/// <summary>
		/// 获取当前日期所在年的第一天日期
		/// </summary>
		/// <param name="date"></param>
		/// <returns></returns>
		public static DateTime YearFirstDay ( this DateTime date )
		{
			return date.ToString ( "yyyy-01-01" ).ToDateTimeValue ( ).Value;
		}

		/// <summary>
		/// 获取当前日期所在年的第一天日期
		/// </summary>
		/// <param name="date"></param>
		/// <returns></returns>
		public static DateTime YearLastDay ( this DateTime date )
		{
			return date.ToString ( "yyyy-12-31" ).ToDateTimeValue ( ).Value;
		}

		/// <summary>
		/// date1（当前时间）不能小于date2，如果小于了date2，则返回date2
		/// </summary>
		/// <param name="date1"></param>
		/// <param name="date2"></param>
		/// <returns></returns>
		public static DateTime NotLessThan ( this DateTime date1, DateTime date2 )
		{
			return date1 < date2 ? date2 : date1;
		}

		/// <summary>
		/// date1（当前时间）不能大于date2，如果大于了date2，则返回date2
		/// </summary>
		/// <param name="date1"></param>
		/// <param name="date2"></param>
		/// <returns></returns>
		public static DateTime NotGreaterThan ( this DateTime date1, DateTime date2 )
		{
			return date1 > date2 ? date2 : date1;
		}

		/// <summary>
		/// 获取当前日期的总毫秒数（从1970-1-1开始计算）
		/// </summary>
		/// <param name="date"></param>
		/// <returns></returns>
		public static double TotalMilliSeconds ( this DateTime date )
		{
			long jsBeginTick = DateTime.Parse ( "1970-1-1" ).Ticks;

			long dt2Ticks = date.ToUniversalTime ( ).Ticks;
			long dt2JsTicks = ( dt2Ticks - jsBeginTick ) / ( 10000 );
			return dt2JsTicks;
		}

		/// <summary>
		///
		/// </summary>
		/// <param name="obj"></param>
		/// <param name="compare"></param>
		/// <returns></returns>
		public static bool IsEquals ( this DateTime obj, DateTime compare )
		{
			if ( compare == null )
			{
				return false;
			}
			return obj.ToString ( "yyyy-MM-dd" ).Equals ( compare.ToString ( "yyyy-MM-dd" ) );
		}
        
        #endregion 日期对象扩展
    }
}
